import random
import re
from datetime import datetime

from flask import abort, jsonify
from flask import current_app
from flask import json
from flask import make_response
from flask import request
from flask import session
from info import constants, db
from info import redis_store
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.response_code import RET
from . import passport_blu
from info.utils.captcha.captcha import captcha


# 退出
@passport_blu.route('/logout')
def logout():

    # 退出登陆清除session中数据
    # 清除数据
    session.pop('user_id', None)
    session.pop('mobile', None)
    session.pop('nick_name', None)
    session.pop('is_admin', None)
    return jsonify(errno=RET.OK, errmsg='退出成功')


# 登陆
@passport_blu.route('/login', methods=["post"])
def login():
    # 1.获取参数：登陆账号，密码
    login_dict = request.json
    mobile = login_dict.get('mobile')
    password = login_dict.get('password')
    # 2.校验参数是否为空，是否符合正则
    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数错误')
    if not re.match('1[35678]\\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号错误')

    # 获取到手机号后，判断是非存在数据
    try:
        user = User.query.filter(User.mobile==mobile).first()
    except Exception as e:
        return jsonify(errno=RET.DBERR,errmsg='参数获取错误')
    if not user:
        return jsonify(errno=RET.NODATA,errmsg='无法查询到该用户，确认是否注册')

    # 3.校验密码是否正确(调用check_password传入需要校验的密码)
    if not user.check_passowrd(password):
        return jsonify(errno=RET.PWDERR,errmsg='密码不正确')

    # 4.数据保存到session中，保存登陆状态
    session['user_id'] = user.id
    session['mobile'] = user.mobile
    session['nick_name'] = user.nick_name
    # 记录用户最后一次登陆的时间
    User.last_login = datetime.now()
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
    # 5.返回ok
    return jsonify(errno=RET.OK, errmsg='登陆成功')


# 注册提交
@passport_blu.route('/register', methods=['post'])
def register():
    # 1.获取参数
    register_dict = request.json
    mobile = register_dict.get('mobile')
    smscode = register_dict.get('smscode')
    password = register_dict.get('password')
    # 2.校验参数
    if not all([mobile, smscode, password]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数获取错误")

    if not re.match('1[35678]\\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号错误')

    # 3查找到数据库存的短信验证码
    try:
        real_smscode = redis_store.get('SMS'+mobile)
    except Exception as e:
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")

    # 没有查询到随机验证码
    if not real_smscode:
        return jsonify(errno=RET.NODATA, errmsg="验证码已过期")

    # 4将客户输入的短信验证码和redis存的验证码进行对比

    if real_smscode != smscode:
        return jsonify(errno=RET.DATAERR, errmsg="验证码输入错误")

    # 5初始化User模型,并且赋值属性
    user = User()
    user.mobile = mobile
    # 由于没有昵称数据，用手机号暂时代替
    user.nick_name = mobile
    # 记录最后一次登陆的时间(当前登陆的时间)
    user.last_login = datetime.now()
    # 密码加密处理
    # user.password_hash = password
    user.password = password

    # 6将数据模型提交到mysql数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="数据库保存失败")

    # 向session中保存数据，表示已经登陆
    session['user_id'] = user.id
    session['mobile'] = user.mobile
    session['nick_name'] = user.nick_name

    # 7 返回注册成功
    return jsonify(errno=RET.OK, errmsg="注册成功")


# 短信验证
@passport_blu.route('/sms_code',methods=['POST'])
def send_sms_code():
    # request.data返回的是json格式的一个字符串
    # parms_dict = json.loads(request.data) 将json格式的字符串转换为字典格式

    # 1.获取参数：手机号，图片验证码数字，随机编码
    parms_dict = request.json
    mobile = parms_dict.get('mobile')
    image_code = parms_dict.get('image_code')
    image_code_id = parms_dict.get('image_code_id')

    # 2.判断参数是否为空，是否符合规则
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数错误')

    if not re.match('1[35678]\\d{9}',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号错误')

    # 3.获取redis里面的图片验证码
    try:
        real_image_code = redis_store.get(image_code_id)
        print(real_image_code)
    except Exception as e:
        return jsonify(errno=RET.DBERR,errmsg='数据库查询错误')

    if not image_code_id:
        return jsonify(errno=RET.NODATA,errmsg='图片验证码已过期')

    # 4.将客户输入的验证码和redis内的验证码进行比对
    if real_image_code.upper() != image_code.upper():
        return jsonify(errno=RET.DATAERR,errmsg='验证码错误')

    # 5.如果匹对成功，则生成短信验证码内容并发送给客户
    # 生成六位随机验证码
    sms_code_str = '%06d' % random.randint(0, 999999)
    current_app.logger.debug("手机验证码是：%s" % sms_code_str)

    # 6.发送短信
    # # result = CCP().send_template_sms(mobile,[sms_code_str,constants.SMS_CODE_REDIS_EXPIRES/5],"1")
    # if result != 0:
    #     return jsonify(errno=RET.THIRDERR,errmsg='短信发送失败')

    # 保存验证码
    try:
        redis_store.set('SMS'+mobile,sms_code_str,constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        return jsonify(errno=RET.DBERR,errmsg='数据保存错误')
    # 7.返回ok
    return jsonify(errno=RET.OK,errmsg='短信发送成功')


# 图片验证码
@passport_blu.route('/image_code')
def get_image_id():
    # （取值，判断，返回）生成图片验证码并返回
    # 1.获取浏览器返回的参数（随机编码）
    # 2.判断参数是否存在
    # 3.生成图片验证码
    # 4.保存图片验证码内容到redis
    # 5.返回验证码图片
    # args取到url ？ 后面的参数
    image_CodeId = request.args.get('imageCodeId', None)


    if not image_CodeId:
        return abort(403)

    # name,text,image = captcha.captcha()会报错？
    name, text, image = captcha.generate_captcha()

    try:
        redis_store.set(image_CodeId, text, constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.erro('e')
        abort(500)

    response = make_response(image)
    response.headers["Content-Type"] = "image/jpg"

    return response


